﻿using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace Tzync
{
    public class Profile
    {
        private String profileName;
        private String profilePath;
        private String rootAddressA;
        private String rootAddressB;
        private bool firstTime;
        private bool secondTime;
        private SystemType systemName;
        private bool hasA;
        private bool hasB;
        private bool checkingForAvailability;
        String cpuIdA = "", cpuIdB = "";

        /// <summary>
        /// Creation for first time on either computer.
        /// </summary>
        /// <param name="cpuID">Unique id for the computer</param>
        /// <param name="profileName">Name of the profile</param>
        /// <param name="rootAddress">Root address associated with the computer</param>

        public Profile(String cpuID, String profileName, String rootAddress)
        {
            this.profileName = profileName;
            String programPath = Path.Combine(Directory.GetCurrentDirectory(), "Tzync");
            profilePath = Path.Combine(programPath, profileName);                        
            firstTime = false;
            secondTime = false;
            hasA = false;
            hasB = false;
            checkingForAvailability = false;
            systemName = SystemType.None;
            rootAddressA = "";
            rootAddressB = "";
            
            Directory.CreateDirectory(profilePath);
            WriteSystem(cpuID, rootAddress);            
            CheckSystem(cpuID);
        }

        /// <summary>
        /// To be called 3rd time onwards.
        /// </summary>
        /// <param name="cpuID">cpuID</param>
        /// <param name="profileName">name of the profile to be created</param>
        public Profile(String cpuID, String profileName)
        {
            this.profileName = profileName;
            systemName = SystemType.None;
            String programPath = Path.Combine(Directory.GetCurrentDirectory(), "Tzync");
            profilePath = Path.Combine(programPath, profileName);
            hasA = false;
            hasB = false;
            checkingForAvailability = true;
            CheckSystem(cpuID);
        }       

        public String ProfileName
        {
            get { return profileName; }
            set { profileName = value; }
        }

        public String ProfilePath
        {
            get { return profilePath; }
            set { profilePath = value; }
        }

        public bool FirstTime
        {
            get { return firstTime; }
            set { firstTime = value; }
        }

        public bool SecondTime
        {
            get { return secondTime; }
            set { secondTime = value; }
        }

        public SystemType SystemName
        {
            get { return systemName; }
            set { systemName = value; }
        }

        public bool HasA
        {
            get { return hasA; }
            set { hasA = value; }
        }

        public bool HasB
        {
            get { return hasB; }
            set { hasB = value; }
        }

        public String CPUIdA
        {
            get { return cpuIdA; }
            set { cpuIdA = value; }
        }

        public String CPUIdB
        {
            get { return cpuIdB; }
            set { cpuIdB = value; }
        }

        public String RootAddressA
        {
            get { return rootAddressA; }
            set { rootAddressA = value; }
        }

        public String RootAddressB
        {
            get { return rootAddressB; }
            set { rootAddressB = value; }
        }

        /// <summary>
        /// Stores the profile information in SystemData.
        /// </summary>
        /// <param name="cpuID">Unique id of the current computer</param>
        /// <param name="rootAddress">Root address of the folder associated with the computer</param>
        private void WriteSystem(String cpuID, String rootAddress)
        {
            int counter = 0;
            TextReader tr;
            StreamWriter SW;
            String input = "";            
            FileStream fs;
            String[] arrWords;

            String systemDataPath = Path.Combine(profilePath, "SystemData");


            if (!File.Exists(systemDataPath))
            {
                // create SystemData for the folder pairs                
                fs = File.Create(systemDataPath);
                fs.Close();

                SW = File.AppendText(systemDataPath);
                SW.WriteLine(cpuID + "|" + rootAddress);
                SW.Close();

                firstTime = true;
            }
            else if (File.Exists(systemDataPath))
            {
                //Open file
                tr = new StreamReader(systemDataPath);
                while ((input = tr.ReadLine()) != null)
                {
                    if (input.Trim().Length != 0)
                    {
                        arrWords = input.Split('|');
                        if (counter == 0)
                        {
                            cpuIdA = arrWords[0];
                        }
                        if (counter == 1)
                        {
                            cpuIdB = arrWords[0];
                        }
                        counter++;
                    }
                }
                tr.Close();

                // second time
                if (counter == 1 && cpuIdA.CompareTo(cpuID) != 0 && !checkingForAvailability)
                {                    
                    SW = File.AppendText(systemDataPath);
                    SW.WriteLine(cpuID + "|" + rootAddress);
                    SW.Close();

                    secondTime = true;
                    cpuIdB = cpuID;
                }
            }
            
        }

        
        /// <summary>
        /// Used to determine which system, if available for 2nd rootaddress and also to fill up the rootaddress
        /// </summary>
        /// <param name="cpuID">Unique id of the current computer</param>
        private void CheckSystem(String cpuID)
        {
            int counter = 0;
            TextReader tr;
            String input = "";
            String[] arrWords;

            String systemDataPath = Path.Combine(profilePath, "SystemData");


             if (File.Exists(systemDataPath))
            {
                //Open file
                tr = new StreamReader(systemDataPath);
                while ((input = tr.ReadLine()) != null)
                {
                    if (input.Trim().Length != 0)
                    {
                        arrWords = input.Split('|');
                        if (counter == 0)
                        {
                            hasA = true;
                            rootAddressA = arrWords[1];
                            cpuIdA = arrWords[0];
                            if (cpuID == arrWords[0])
                            {
                                systemName = SystemType.Host;
                            }
                        }
                        if (counter == 1)
                        {
                            hasB = true;
                            rootAddressB = arrWords[1];
                            cpuIdB = arrWords[0];
                            if (cpuID == arrWords[0])
                            {
                                systemName = SystemType.Guest;   
                            }
                        }
                        counter++;
                    }
                }
                tr.Close();
            }
        }

        /// <summary>
        /// This function is called when the rootFolder in either A(Host) or B(Guest) is moved/renamed
        /// </summary>

        public void WriteSystem()
        {
            String systemDataPath = Path.Combine(profilePath, "SystemData");
            File.Delete(systemDataPath);

            StreamWriter SW;

            FileStream fs;
            fs = File.Create(systemDataPath);
            fs.Close();

            SW = File.AppendText(systemDataPath);
            SW.WriteLine(cpuIdA + "|" + rootAddressA);
            if(hasB)
             SW.WriteLine(cpuIdB + "|" + rootAddressB);
            SW.Close();
        }               
/*
        public void WriteToFile(String path, List<String> folderPairs)
        {
            StreamWriter SW;
            File.Delete(path);
            FileStream fs = File.Create(path);
            fs.Close();

            SW = File.AppendText(path);
            foreach (String str in folderPairs)
            {
                SW.WriteLine(str);
            }
            SW.Close();
        }
        */

        /// <summary>
        /// Deletes all files and folders inside the specified directory. To be removed to Utilities in v2.0
        /// </summary>
        /// <param name="dirInfo">Directory to be deleted</param>
        public void DeleteDirectory(DirectoryInfo dirInfo)
        {
            // Copy all files.
            FileInfo[] files = dirInfo.GetFiles();
            FileAttributes fileAtts;
            DirectoryInfo dirDest;
            foreach (FileInfo file in files)
            {
                fileAtts = File.GetAttributes(file.FullName);
                File.SetAttributes(file.FullName, fileAtts & ~FileAttributes.ReadOnly);
                file.Delete();
            }

            // Process subdirectories.
            DirectoryInfo[] dirs = dirInfo.GetDirectories();
            foreach (DirectoryInfo dir in dirs)
            {
                string destinationDir = Path.Combine(dirInfo.FullName, dir.Name);
                dirDest = new DirectoryInfo(destinationDir);

                // Call CopyDirectory() recursively.
                DeleteDirectory(dirDest);
                dirDest.Delete();
            }
        }
    }
}
